本篇同步發布於Blog: [解題] POJ - 2431 Expedition
PKU Online Judge
2431 - Expedition
http://poj.org/problem?id=2431
有一輛車子要開往城鎮,距離為L單位,且車上目前有P單位的燃料。路上會有N(1 <= N <= 10000)間的加油站,每間加油站距離城鎮x單位、並能補充p單位的燃料。車子每行駛1單位的距離就得消耗1單位的燃料,而車子的燃料容量無限大,求車子抵達城鎮時的最少加油次數,如果達不到則輸出-1。
範例輸入是4間加油站,需要在第1家(15 10)和第2家(11 5)加油站加油,才能抵達成鎮。
4
4 4
5 2
11 5
15 10
25 10
2
這題需轉換問題,可以看成是當車子開到某站時,如果行經距離超過燃料箱的油量,則檢查經過的加油站的備用油,先從最大量的油倒進燃料箱,直到超過消耗量或者仍無法滿足消耗量。
最大量的油的儲存方式是使用Priority Queue。
以範例輸入來看:
題目測資會有些陷阱,比如加油站的位置不一定由小到大,需要自己排序。或者加油站的補給量有可能是0.......很好玩的測資。
實作也把城鎮當作最後一家加油站,這樣距離/扣油量的計算才會完整。
難度為Medium
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
struct Stop{
	int dist, amount;
};
bool cmp(const Stop &a, const Stop &b)
{
    return a.dist < b.dist;
}
int main() {
	int n;
	Stop stops[10005];
	int L, curAmount;
	while(cin >> n){
		int ans = 0;
		bool notToTown = false;
		priority_queue<int, vector<int>, less<int> > q;
		for(int i = 0 ; i < n;++i){
			cin >> stops[i].dist >> stops[i].amount;
		}
		cin >> L >> curAmount;
		
		
		stops[n].dist = 0;
		stops[n].amount = 0;
		
		sort(stops, stops + (n+1), cmp);
		
		int curLength = L;
		
		for(int i = n ; i >= 0;--i){
			int curDistance = curLength - stops[i].dist;
			
			while(curAmount - curDistance < 0){
				if(q.empty()){
					notToTown = true;
					break;
				}else{
					curAmount += q.top();
					q.pop();
					ans++;
				}
			}
			
			curAmount -= curDistance;
			q.push(stops[i].amount);
			curLength = stops[i].dist;
		}
		
		if(notToTown){
			cout << "-1" << endl;
		}
		else{
			cout << ans << endl;
		}
	}
	return 0;
}
https://github.com/u8989332/ProblemSolving/blob/master/PKUOnlineJudge/2400-2499/2431.cpp